package com.jweb.framework.ws.server;

import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;

import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.MessageEndpoint;
import org.springframework.ws.server.endpoint.mapping.AbstractEndpointMapping;
import org.springframework.xml.transform.TraxUtils;

import com.jweb.framework.core.channel.ChannelContext;
import com.jweb.framework.core.channel.Endpoint;
import com.jweb.framework.core.channel.URIEndpointMapping;
import com.jweb.framework.core.impl.DefaultChannelContext;
import com.jweb.framework.core.support.Utils;

/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：webServices 服务方映射类
 */
public class WebServiceEndpointMapping extends AbstractEndpointMapping implements MessageEndpoint {
	
	private URIEndpointMapping uriEndpointMapping = new InnerURIEndpointMapping(this);
	
	public void setDefault(Endpoint<MessageContext , MessageContext> endpoint){
		uriEndpointMapping.setDefault(endpoint);
	}
	
	public void setMapping(Map mapping){
		uriEndpointMapping.setMapping(mapping);
	}
	
	@Override
	public void invoke(MessageContext messageContext) throws Exception {
		
		DefaultChannelContext defaultChannelContext = new DefaultChannelContext(messageContext , messageContext);
		
		try {
			Endpoint endpoint = uriEndpointMapping.mapping(defaultChannelContext);
			endpoint.service(defaultChannelContext);
		} catch (Exception e) {
			if(Utils.shouldLogging(e)){
				this.logger.error("web service error" , e);
			}
			throw e ;
		} catch (Error err) {
			if(Utils.shouldLogging(err)){
				this.logger.error("web service error" , err);
			}
			throw err ;
		}
	}

	@Override
	protected Object getEndpointInternal(MessageContext messageContext)
			throws Exception {
		return this ;
	}
	
	protected String getURIString(MessageContext messageContext) {
		Source source = messageContext.getRequest().getPayloadSource() ;
		if(TraxUtils.isStaxSource(source)){
			XMLStreamReader xmlStreamReader = TraxUtils.getXMLStreamReader(source);
			try {
				if(xmlStreamReader.next() != 1) ;
			} catch (XMLStreamException e) {
				throw new IllegalStateException(e);
			}
			
			QName qname = xmlStreamReader.getName();
			return qname.getNamespaceURI();
		}
		
		throw new UnsupportedOperationException("just support StaxSource . ");
	}
	
	
	class InnerURIEndpointMapping extends URIEndpointMapping<MessageContext , MessageContext> {
		
		public InnerURIEndpointMapping(WebServiceEndpointMapping webServiceEndpointMapping){
			
		}
		
		@Override
		protected String getURIString(ChannelContext<MessageContext, MessageContext> channelContext) {
			
			return WebServiceEndpointMapping.this.getURIString((MessageContext)channelContext.getRequest()) ;
		}
		
	}

}
